package com.fast.ThreadPoolFactory;

import cn.hutool.core.thread.NamedThreadFactory;

import java.util.concurrent.*;

/**
 * CompletableFuture
 * 主要是用于AB都执行成功，然后执行C
 *
 * runAfterBoth   A和B都执行完了，不要A和B的结果，再执行C，无返回结果
 * thenAcceptBoth A和B都执行完了，需要A和B的结果，再执行C，无返回结果
 * thenCombine    A和B都执行完了，需要A和B的结果，再执行C，有返回结果
 *
 * @author hjw
 * @since 2022年07月17日 18:13:00
 */
public class CF4_runAfterBoth_thenAcceptBoth_thenCombine {

    public static ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() * 2,
            Runtime.getRuntime().availableProcessors() * 2,
            10,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(300),
            new NamedThreadFactory("core_thread_pool_",true),
            new ThreadPoolExecutor.AbortPolicy()
    );

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("主线程开始了-----------");


        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            System.out.println("runAfterBoth线程" + Thread.currentThread().getName() + "--------把任务A执行完了");
            return "hello";
        }, threadPoolExecutor);

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            System.out.println("runAfterBoth线程" + Thread.currentThread().getName() + "--------把任务B执行完了");
            return "world";
        }, threadPoolExecutor);

        //1.A和B都执行完了，不要A和B的结果，再执行C，无返回结果
        futureA.runAfterBothAsync(futureB, () -> System.out.println("任务C执行完了"), threadPoolExecutor);


        //2.A和B都执行完了，需要A和B的结果，再执行C，无返回结果
        futureA.thenAcceptBothAsync(futureB,(f1,f2)->{
            System.out.println("任务C的输出结果:"+f1+"_"+f2);
        },threadPoolExecutor);

        //3.A和B都执行完了，需要A和B的结果，再执行C，有返回结果
        CompletableFuture<String> futureC = futureA.thenCombineAsync(futureB, (f1, f2) -> {
            System.out.println("任务C执行完了有返回值");
            return f1 + "==" + f2;
        }, threadPoolExecutor);
        System.out.println("futureC返回值 = " + futureC.get());
        System.out.println("主线程结束了--------------");
    }
}
